package soar.template.springboot.service.hello.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.stereotype.Service;

import soar.template.springboot.service.rmi.hello.CreateAccountRequest;
import soar.template.springboot.service.rmi.hello.CreateAccountResponse;
import soar.template.springboot.share.entity.log.UserLog;
import soar.template.springboot.share.entity.main.UserInfo;

@Service
public class CreateAccountService extends BaseService
{
    private final static Logger logger = LoggerFactory
            .getLogger(CreateAccountService.class);

    public CreateAccountResponse run(CreateAccountRequest request)
    {
        String login;
        String name;
        int age;
        String address;
        try
        {
            login = Optional.ofNullable(request.getLogin()).map(String::trim)
                    .orElse("");
            name = Optional.ofNullable(request.getName()).map(String::trim)
                    .orElse("");
            age = request.getAge();
            address = Optional.ofNullable(request.getAddress())
                    .map(String::trim).orElse("");
            if (login.isEmpty())
            {
                logger.error("login empty");
                throw new Exception();
            }
            if (name.isEmpty())
            {
                logger.error("name empty");
                throw new Exception();
            }
            if (age <= 18)
            {
                logger.error("age({}) invalid", age);
                throw new Exception();
            }
        }
        catch (Exception e)
        {
            logger.error("request invalid");
            return create_response(9999, "参数错误");
        }

        CreateAccountResponse response = null;

        UserInfo user_info;
        UserLog user_log;
        Date now = new Date();

        EntityManager main_em = null;

        int user_id = 0;
        try
        {
            main_em = mainEntityManagerFactory.createEntityManager();

            main_em.getTransaction().begin();

            user_info = new UserInfo();
            user_info.setCreate_time(now);
            user_info.setUpdate_time(now);
            user_info.setLogin(login);
            user_info.setName(name);
            user_info.setAge(age);
            user_info.setAddress(address);
            main_em.persist(user_info);

            main_em.getTransaction().commit();

            logger.info("create user_info succeed, id:{}", user_info.getId());

            user_id = user_info.getId();
        }
        catch (Exception e)
        {
            if (e.getMessage() != null)
                logger.error("fail: {}", e);
            try
            {
                if (main_em != null && main_em.getTransaction().isActive())
                    main_em.getTransaction().rollback();
            }
            catch (Exception er)
            {
                logger.error("rollback fail: {}", er);
            }
            if (response == null)
                response = create_response(9999, "未知错误");
            return response;
        }
        finally
        {
            if (main_em != null)
                main_em.close();
        }

        EntityManager log_em = null;
        try
        {
            log_em = logEntityManagerFactory.createEntityManager();

            log_em.getTransaction().begin();

            user_log = new UserLog();
            user_log.setCreate_time(now);
            user_log.setUser_id(user_id);
            user_log.setContent("创建");
            log_em.persist(user_log);

            log_em.getTransaction().commit();

            logger.info("create user_log succeed, id:{}", user_log.getId());
        }
        catch (Exception e)
        {
            if (e.getMessage() != null)
                logger.error("fail: {}", e);
            try
            {
                if (log_em != null && log_em.getTransaction().isActive())
                    log_em.getTransaction().rollback();
            }
            catch (Exception er)
            {
                logger.error("rollback fail: {}", er);
            }
            if (response == null)
                response = create_response(9999, "未知错误");
            return response;
        }
        finally
        {
            if (log_em != null)
                log_em.close();
        }

        RedisConnection main_redis_connection = null;
        try
        {
            main_redis_connection = mainRedisConnectionFactory.getConnection();

            List<byte[]> args = new ArrayList<>();
            args.add("name".getBytes());
            List<byte[]> list = main_redis_connection.hMGet(
                    ("user_" + user_info.getId()).getBytes(),
                    args.toArray(new byte[0][]));
            list.forEach(x -> {
                logger.info("{}", new String(x));
            });

            Map<byte[], byte[]> map = new HashMap<>();
            map.put("name".getBytes(), user_info.getName().getBytes());
            map.put("last_log".getBytes(),
                    (user_log.getId() + " "
                            + new SimpleDateFormat("")
                                    .format(user_log.getCreate_time())
                            + " " + user_log.getContent()).getBytes());
            main_redis_connection
                    .hMSet(("user_" + user_info.getId()).getBytes(), map);
        }
        catch (Exception e)
        {
            logger.error("fail: {}", e);
        }
        finally
        {
            if (main_redis_connection != null)
                main_redis_connection.close();
        }

        try
        {
            String key = "user_" + user_info.getId();
            String field_name = "name";
            String field_last_log = "last_log";

            List<Object> fields = mainRedisTemplate.opsForHash().multiGet(key,
                    Arrays.asList(field_name, field_last_log));
            String name_in = Optional.ofNullable(fields.get(0))
                    .map(x -> (String) x).map(String::trim).orElse("");

            mainRedisTemplate.opsForHash().put(key, field_name,
                    user_info.getName());
            Map<String, String> map = new HashMap<>();
            map.put(field_name, user_info.getName());
            map.put(field_last_log,
                    user_log.getId() + " "
                            + new SimpleDateFormat("")
                                    .format(user_log.getCreate_time())
                            + " " + user_log.getContent());
            mainRedisTemplate.opsForHash().putAll(key, map);
        }
        catch (Exception e)
        {
            logger.error("fail: {}", e);
        }

        try
        {
            Query query = new BasicQuery(String
                    .format("{ _id:{$ne:'%s'}, active:%d }", "default", 1),
                    "{ _id:1, xids:1 }");
            // 选取整条记录，再选择映射，字段太大的时候不可取！
            // Query query = new Query(Criteria.where("_id").ne("default")
            // .and("active").is(1));
//            List<CidXids> list = Optional
//                    .ofNullable(mainMongoTemplate.find(query, CidXids.class))
//                    .orElse(new ArrayList<>());
        }
        catch (Exception e)
        {
            logger.error("fail: {}", e);
        }

        response = create_response(0, "成功");

        return response;
    }

    private CreateAccountResponse create_response(int error, String errmsg)
    {
        CreateAccountResponse response = new CreateAccountResponse(error,
                errmsg);
        return response;
    }
}
